/*
 * AppClient.cpp
 *
 *  Created on: 22 sept. 2009
 *      Author: CHETIER
 */

#include <iostream>

#include <SFML/Network.hpp>
#include <SFML/Graphics.hpp>

#include "ClientManager.h"
#include "PacketInfo.h"
#include "PacketTransmitter.h"
#include "ClientState.h"
#include "Config.h"

//Client Manager
ClientManager clientManager;
sf::Mutex mutexClientManager;
sf::SocketUDP Listener;
sf::IPAddress ServerAdress;

void PacketReceiver(void* Data)
{
	while(true)
	{
		PacketInfo packetToReceive;
		sf::IPAddress sender;
		unsigned short port;

		if (Listener.Receive(packetToReceive, sender, port) != sf::Socket::Done)
		{
			std::cout << "error while receiving packet" << std::endl;
			return;
		}

		//Transform packet into ClientInfo
		mutexClientManager.Lock();
		packetToReceive >> clientManager;
		mutexClientManager.Unlock();
		//std::cout << clientManager.size() << "clients recovered" << std::endl;
	}
}

int main()
{
	//Initialization
	ClientInfo clientInfo = {false, false, false, false, 200, 200, -1, "", "127.0.0.1"};

	std::cout<< "Type an id for the client"<< std::endl;
	std::cin >> clientInfo.id;

	std::cout<< "Type a name for the client"<< std::endl;
	std::cin>> clientInfo.name;

	do
	{
		std::cout<< "Type the Ip adress of the server"<<std::endl;
		std::cin >> ServerAdress;
	}
	while(!ServerAdress.IsValid());

	bool mustSendPacket = false;

	//Window application initialization
	sf::RenderWindow App(sf::VideoMode(800, 600, 32), "Client");

	if (!Listener.Bind(PORT_SERVER_TO_CLIENT))
	{
		std::cout << "Error while binding listener socket!" << std::endl;
		return EXIT_FAILURE;
	}

	sf::Thread threadPacketReceiver(&PacketReceiver);
	threadPacketReceiver.Launch();

	PacketTransmitter initPacketTransmitter;
	initPacketTransmitter.SendToServer(ServerAdress, clientInfo);

	sf::Font myFont;// = sf::Font::GetDefaultFont();
	if (!myFont.LoadFromFile("data/ARIAL.TTF", 12))
	{
	    std::cout<<"error while loading font"<<std::endl;
	    return EXIT_FAILURE;
	}

	//Main loop
	while (App.IsOpened())
	{
		if( App.GetInput().IsKeyDown(sf::Key::Left)!= clientInfo.left)
			clientInfo.left = !clientInfo.left, mustSendPacket = true;
		if(App.GetInput().IsKeyDown(sf::Key::Right)!= clientInfo.right)
			clientInfo.right = !clientInfo.right, mustSendPacket = true;
		if(App.GetInput().IsKeyDown(sf::Key::Up)!= clientInfo.up)
			clientInfo.up = !clientInfo.up, mustSendPacket = true;
		if(App.GetInput().IsKeyDown(sf::Key::Down)!= clientInfo.down)
			clientInfo.down = !clientInfo.down, mustSendPacket = true;

		//Send client info
		PacketTransmitter packetTransmitter;
		if(mustSendPacket)
		{
			//Send packet asynchronously
			packetTransmitter.SendToServer(ServerAdress, clientInfo);
		}

		//reset flag
		mustSendPacket = false;

		//Check events
		sf::Event Event;
		while (App.GetEvent(Event))
			if (Event.Type == sf::Event::Closed) App.Close();

		float ElapsedTime = App.GetFrameTime();

		App.Clear();
		mutexClientManager.Lock();
		for(ClientManager::iterator i = clientManager.begin(); i != clientManager.end(); ++i)
		{
			//Think
			if(i->left) i->x -= 50*ElapsedTime;
			if(i->right) i->x += 50*ElapsedTime;
			if(i->up) i->y -= 50*ElapsedTime;
			if(i->down) i->y += 50*ElapsedTime;

			//Display sprite
			sf::Shape sprite = sf::Shape::Circle(
				i->x,
				i->y,
				10,
				i->id != clientInfo.id?
					sf::Color(100,30,255,255):
					sf::Color(255,255,255,255));
			App.Draw(sprite);

			sf::String spriteName(i->name, myFont, 12);
			spriteName.SetColor(sf::Color(255,255,255,128));
			spriteName.SetPosition(i->x - spriteName.GetRect().GetWidth()/2, i->y - 30);
			App.Draw(spriteName);
		}
		mutexClientManager.Unlock();
		App.Display();
	}


	threadPacketReceiver.Terminate();
	std::cout << "client is going to quit now..."<< std::endl;

	return EXIT_SUCCESS;
}
